﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Documents;
using TableTypes;
using Speakup;
using System.Windows.Input;

namespace SpeakupUI
{
    class ClassPanel: ContentControl
    {
        public static Dictionary<ClassStatus, Brush> ClassBackgrounds;
        public static Brush DefaultClassBackground;

        public static Dictionary<ClassStatus, Brush> HighlightedClassBackgrounds;
        public static Brush DefaultHighlightedClassBackground;

        public static Dictionary<ClassType, string> ClassTypeTitles;
        public static Dictionary<ClassType, string> ShortClassTypeTitles;

        public static Size SmallSize = new Size(35, 35);
        public static bool UseSmallSizeDetection = true;

        static ClassPanel()
        {
            Color blueColor = Color.FromRgb(51,204,255);            
            Color waitListColor = Color.FromRgb(150,150,150);
            
            ClassBackgrounds = new Dictionary<ClassStatus, Brush>();
            ClassBackgrounds[ClassStatus.Available]         = Brushes.LightGreen;
            ClassBackgrounds[ClassStatus.AvailableWaitList] = GetGradientBrush(Colors.LightGreen, waitListColor);
            ClassBackgrounds[ClassStatus.Reserved]          = new SolidColorBrush(blueColor);
            ClassBackgrounds[ClassStatus.ReservedWaitList]  = GetGradientBrush(blueColor, waitListColor);


            DefaultClassBackground = Brushes.Gray;


            Color hgColor = Colors.Orange;
            Color hgWaitListColor = Colors.OrangeRed;
            HighlightedClassBackgrounds = new Dictionary<ClassStatus, Brush>();

            HighlightedClassBackgrounds[ClassStatus.AvailableWaitList] =
                GetGradientBrush(Colors.LightGreen, hgWaitListColor);
            HighlightedClassBackgrounds[ClassStatus.ReservedWaitList] =
                GetGradientBrush(blueColor, hgWaitListColor);
            HighlightedClassBackgrounds[ClassStatus.Available] =
                GetGradientBrush(Colors.LightGreen, hgColor);             
            HighlightedClassBackgrounds[ClassStatus.Reserved] =
                GetGradientBrush(blueColor, hgColor);                                                           

            DefaultHighlightedClassBackground = Brushes.LightPink;

            ClassTypeTitles = new Dictionary<ClassType, string>();
            ClassTypeTitles[ClassType.Club] = "Club";
            ClassTypeTitles[ClassType.Group] = "Group Class";
            ClassTypeTitles[ClassType.FirstClass] = "First Class";
            ClassTypeTitles[ClassType.ProgressFollowup] = "Progress Follow-up";
            ClassTypeTitles[ClassType.Grammar] = "Grammar";
            ClassTypeTitles[ClassType.Reading] = "Reading";
            ClassTypeTitles[ClassType.Writing] = "Writing";
            ClassTypeTitles[ClassType.Conversation] = "Conversation";

            ShortClassTypeTitles = new Dictionary<ClassType, string>();
            ShortClassTypeTitles[ClassType.Club] = "CC";
            ShortClassTypeTitles[ClassType.Group] = "GC";
            ShortClassTypeTitles[ClassType.FirstClass] = "FC";
            ShortClassTypeTitles[ClassType.ProgressFollowup] = "PF";
            ShortClassTypeTitles[ClassType.Grammar] = "Gr";
            ShortClassTypeTitles[ClassType.Reading] = "Rd";
            ShortClassTypeTitles[ClassType.Writing] = "Wr";
            ShortClassTypeTitles[ClassType.Conversation] = "Con";
        }

        static private Brush GetGradientBrush(Color start, Color stop)
        {
            GradientStopCollection stops = new GradientStopCollection();
                        
            stops.Add(new GradientStop(stop, 0));
            stops.Add(new GradientStop(start, 1));

            return new LinearGradientBrush(stops, 0);
        }        

        static private Brush GetClassBrush(ClassStatus status)
        {
            if(ClassBackgrounds.Keys.Contains(status))
            {
                return ClassBackgrounds[status];
            }

            return DefaultClassBackground;
        }
        static private Brush GetHighlightedClassBrush(ClassStatus status)
        {
            if (HighlightedClassBackgrounds.Keys.Contains(status))
            {
                return HighlightedClassBackgrounds[status];
            }

            return DefaultHighlightedClassBackground;
        }

        static private String GetClassTitle(Class speakupClass)
        {
            if(ClassTypeTitles.Keys.Contains(speakupClass.ClassName.Type))
            {
                return ClassTypeTitles[speakupClass.ClassName.Type];
            }

            return speakupClass.ClassName.ToString();
        }
        static private String GetShortClassTitle(Class speakupClass)
        {
            if (ShortClassTypeTitles.Keys.Contains(speakupClass.ClassName.Type))
            {
                return ShortClassTypeTitles[speakupClass.ClassName.Type];
            }

            return speakupClass.ClassName.ToString();
        }


        public Class SpeakupClass { get; private set; }

        private DockPanel Panel;
        private Border Border;
        private TextBlock Title;

        private bool m_fadedOut = false;
        public bool FadedOut
        {
            get
            {
                return m_fadedOut;
            }
            set
            {
                if (m_fadedOut != value)
                {
                    m_fadedOut = value;
                    UpdateFadeOut();
                }
            }
        }

        private bool m_highlight = false;
        private int m_old_zIndex = 0;
        public bool Highlight
        {
            get
            {
                return m_highlight;
            }
            set
            {
                if (m_highlight != value)
                {
                    m_highlight = value;
                    UpdateHighlightStatus();

                    if (HighlightEvent != null)
                    {
                        HighlightEvent(this, null);
                    }
                }
            }
        }

        private bool m_selected = false;
        public bool Selected
        {
            get
            {                
                return m_selected;
            }
            set
            {
                if (value != m_selected)
                {
                    m_selected = value;
                    UpdateSelectedStatus();

                    if (SelectionEvent != null)
                    {
                        SelectionEvent(this, null);
                    }
                }
            }
        }
        
        public ClassPanel(Speakup.Class speakupClass)
        {
            SpeakupClass = speakupClass;

            TimeSlot timeSlot = new TimeSlot(speakupClass.ClassTime.Begin, speakupClass.ClassTime.End);
            this.SetValue(TimeSheet.TimeSlotProperty, timeSlot);
            this.SetValue(TimeSheet.DaySlotProperty, speakupClass.ClassTime.Date);

            
            VerticalAlignment = VerticalAlignment.Stretch;
            HorizontalAlignment = HorizontalAlignment.Stretch;

            /* border */
            Border = new Border();
            Border.BorderBrush = Brushes.Black.Clone();
            Border.BorderThickness = new Thickness(0.5);

            Content = Border;
            
            /* panel */
            DockPanel RawPanel = new DockPanel();
            RawPanel.Background = Brushes.White;
            Border.Child = RawPanel;

            Panel = new DockPanel();
            Panel.VerticalAlignment = VerticalAlignment.Stretch;
            RawPanel.Children.Add(Panel);
            
            /* title */
            Title = new TextBlock();
            Title.TextWrapping = TextWrapping.Wrap;
            Title.VerticalAlignment = VerticalAlignment.Center;
            Title.HorizontalAlignment = HorizontalAlignment.Center;
            Title.TextAlignment = TextAlignment.Center;
            
            UpdateTitle();
            UpdateFadeOut();
            UpdateHighlightStatus();
            UpdateSelectedStatus();

            Panel.Children.Add(Title);
        }

        public void UpdateTitle()
        {
            string title;

            bool useShortTitle = false;

            if(UseSmallSizeDetection == false || RenderSize.IsEmpty)
            {
                useShortTitle = false;
            }
            else
            {
                if (RenderSize.Height > SmallSize.Height &&
                    RenderSize.Width > SmallSize.Width)
                {
                    useShortTitle = false;
                }
                else
                {
                    useShortTitle = true;
                    
                }   
            }


            if (useShortTitle)
            {
                title = GetShortClassTitle(SpeakupClass);
            }
            else
            {
                title = GetClassTitle(SpeakupClass);
                if (SpeakupClass.ClassName.Kind == ClassKind.Club)
                {
                    title += "\n" + SpeakupClass.ClassName.Name;
                }
                else if (SpeakupClass.ClassName.Kind == ClassKind.Group)
                {
                    title += "\n" + SpeakupClass.ClassName.Name;
                }
            }

            Title.Inlines.Clear();

            
            Span sp = new Span(new Run(title));
            
            if(SpeakupClass.Modified)
            {
                title += "*";
                sp = new Bold(new Underline( new Run(title)));
            }           


            Title.Inlines.Add(sp);
        }
        public void UpdateFadeOut()
        {
            if (m_fadedOut)
            {
                Panel.Background = Brushes.LightGray;
            }
            else
            {
                Panel.Background = GetClassBrush(SpeakupClass.ClassStatus);
                UpdateHighlightStatus();
                UpdateSelectedStatus();
            }
        }
        public void UpdateHighlightStatus()
        {
            if (m_highlight || m_selected)
            {
                Panel.Background = GetHighlightedClassBrush(SpeakupClass.ClassStatus);

                m_old_zIndex = DockPanel.GetZIndex(this);
                DockPanel.SetZIndex(this, m_old_zIndex + 1);
            }
            else
            {
                Panel.Background = GetClassBrush(SpeakupClass.ClassStatus);
                DockPanel.SetZIndex(this, m_old_zIndex);

                if (m_fadedOut)
                {
                    UpdateFadeOut();
                }
            }
            UpdateTitle();

            
        }
        public void UpdateSelectedStatus()
        {          
            if (m_selected)
            {
                Highlight = true;
                Border.BorderBrush = Brushes.Red;
                Border.BorderThickness = new Thickness(2);            
            }
            else
            {                
                Border.BorderBrush = Brushes.Black;
                Border.BorderThickness = new Thickness(0.5);                
            }
            UpdateHighlightStatus();
        }

        protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            UpdateTitle();
        }
        protected override void OnMouseEnter(MouseEventArgs e)
        {
            base.OnMouseEnter(e);

            if (IsEnabled)
            {
                Highlight = true;
            }
        }

        protected override void OnMouseLeave(MouseEventArgs e)
        {
            base.OnMouseLeave(e);

            if (IsEnabled)
            {
                Highlight = false;                
            }
        }
        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            if (IsEnabled)
            {
                if (Selected)
                {
                    Selected = false;
                    Highlight = true;
                }
                else
                {
                    Selected = true;
                }
            }
        }

        protected override void OnMouseDoubleClick(MouseButtonEventArgs e)
        {
            base.OnMouseDoubleClick(e);

            if (SpeakupClass.Modified)
            {
                SpeakupClass.CancelModification();
            }
            else
            {
                switch (SpeakupClass.ClassStatus)
                {
                    case ClassStatus.Available:
                        SpeakupClass.DesiredStatus = ClassStatus.Reserved;
                        break;
                    case ClassStatus.Reserved:
                        SpeakupClass.DesiredStatus = ClassStatus.Available;
                        break;
                    case ClassStatus.AvailableWaitList:
                        SpeakupClass.DesiredStatus = ClassStatus.ReservedWaitList;
                        break;
                    case ClassStatus.ReservedWaitList:
                        SpeakupClass.DesiredStatus = ClassStatus.AvailableWaitList;
                        break;
                }
            }

            {
                UpdateTitle();
                if (Highlight)
                {
                    Highlight = true;
                    Highlight = false;
                }
                else
                {
                    Highlight = false;
                    Highlight = true;
                }
            }

            
        }

        public event EventHandler<EventArgs> HighlightEvent;
        public event EventHandler<EventArgs> SelectionEvent;
    }
}
